package com.tbit.main.controller;

import cn.hutool.core.util.StrUtil;
import com.tbit.common.constant.OperationPlatform;
import com.tbit.common.entity.UserOpLog;
import com.tbit.main.common.JsonResult;
import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.main.constant.OperateLog;
import com.tbit.main.constant.UserMsgConstant;
import com.tbit.main.controller.interceptor.LoginUserContextHolder;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import com.tbit.main.service.impl.UserOpLogService;
import com.tbit.main.util.Assert;
import com.tbit.main.util.DateTimeUtil;
import com.tbit.main.util.LogUtil;
import com.tbit.main.util.ObjectUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户黑名单
 *
 * @author Leon
 * 2020年4月3日 下午4:10:14
 */
@RestController
@RequestMapping("/userBlackList")
public class UserBlackListController {
    @Autowired
    private UserBlackListService userBlackListService;
    @Autowired
    private UserService userService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private UserMsgService userMsgService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private BlackListLogService blackListLogService;
    @Autowired
    private UserOpLogService userOpLogService;

    /**
     * 添加
     */
    @RequestMapping("/add")
    public JsonResult add(String token, UserBlackList userBlackList,
                          @RequestParam(value = "state", required = false) Integer state,
                          @RequestParam(value = "idNOSwitch", required = false) Integer idNOSwitch
    ) {
        /* 校验 */
        Assert.notNull(userBlackList.getAccountId(), "AccountUser.agentId.notNull");
        Assert.notNull(userBlackList.getExpireTime(), "UserBlackList.expireTime.notNull");
        Assert.notNull(userBlackList.getRemark(), "System.remark.notNull");
        if (StrUtil.isNotEmpty(userBlackList.getPhone()) && userBlackList.getPhone().length() > 20){
            throw new BaseException("手机号码过长");
        }else if (StrUtil.isNotEmpty(userBlackList.getRemark()) && userBlackList.getRemark().length() > 255){
            throw new BaseException("用户黑名单备注过长");
        }
        AccountUser accountUser = tokenService.getAccount(token);

        /**查询品牌id*/
        Account account = accountService.getByAccountId(userBlackList.getAccountId());
        if (account == null) {
            throw new BaseException("System.account.notExist");
        }

        Account accountAgent = accountService.getByAccountId(account.getParentId());
        if (accountAgent == null) {
            throw new BaseException("System.account.notExist");
        }

        userBlackList.setAccountId(accountAgent.getParentId());

        User user = new User();
        if (userBlackList.getPhone() != null) {
            /**查询用户id*/
            user = userService.getByPhone(userBlackList.getAccountId(), userBlackList.getPhone());
            if (user == null) {
                //预拉黑
                LogUtil.info("预拉黑[" + userBlackList.getPhone() + "]");
                userBlackListService.setUserBlackListByPhoneBatch(userBlackList.getAccountId(), userBlackList.getPhone(), userBlackList.getExpireTime(),userBlackList.getPhotosUrl());
                return JsonResult.succ();
            }
            userBlackList.setIdNO(user.getIdNO());
        } else if (userBlackList.getIdNO() != null) {
            idNOSwitch = 1;
        }

        /**
         * 判断是否添加身份证
         */
        if (idNOSwitch == null) {
            idNOSwitch = 0;
        }
        List<UserBlackList> blackLists = new LinkedList<>();
        List<BlackListLog> blackListLogs = new LinkedList<>();
        if (idNOSwitch.equals(1)) {
            //判断用户是否实名
            if (user.getIdNO() == null){
                throw new BaseException("用户未实名，级联拉黑身份证失败");
            }
            List<User> users = new LinkedList<>();
            List<UserBlackList> userBlackLists = new LinkedList<>();
            if (StringUtils.isNotEmpty(userBlackList.getIdNO())) {
                users = userService.getAccountIdIdNO(userBlackList.getAccountId(), userBlackList.getIdNO());
                userBlackLists = userBlackListService.getByIdNO(userBlackList.getAccountId(), userBlackList.getIdNO());
            } else {
                users.add(user);
            }
            List<Integer> userId = new LinkedList<>();
            if (userBlackLists != null && userBlackLists.size() > 0) {
                userId = userBlackLists.stream().map(UserBlackList::getUserId).collect(Collectors.toList());
            }


            if (users != null && users.size() > 0) {
                for (User userBlack : users) {
                    if (userId.contains(userBlack.getUserId())) {
                        userBlackListService.del(userBlack.getUserId());
                    }
                    UserBlackList userBlackListInsert = new UserBlackList();
                    userBlackListInsert.setAccountId(accountAgent.getParentId());
                    userBlackListInsert.setUserId(userBlack.getUserId());
                    userBlackListInsert.setAddTime(DateTimeUtil.getNowTime());
                    userBlackListInsert.setIdNO(userBlack.getIdNO());
                    userBlackListInsert.setRemark(userBlackList.getRemark());
                    userBlackListInsert.setExpireTime(userBlackList.getExpireTime());
                    userBlackListInsert.setPhone(userBlack.getPhone());
                    userBlackListInsert.setPhotosUrl(userBlackList.getPhotosUrl());
                    blackLists.add(userBlackListInsert);

                    BlackListLog blackListLog = new BlackListLog();
                    blackListLog.setAccountId(userBlackListInsert.getAccountId());
                    blackListLog.setUserId(userBlackListInsert.getUserId());
                    blackListLog.setUserPhone(userBlackListInsert.getPhone());
                    blackListLog.setAddAccountUserId(accountUser.getAccountUserId());
                    blackListLog.setAddAccountUserPhone(accountUser.getPhone());
                    blackListLog.setAddTime(userBlackListInsert.getAddTime());
                    blackListLog.setRemark(userBlackListInsert.getRemark());
                    blackListLog.setIdNO(userBlackListInsert.getIdNO());
                    blackListLog.setReason(userBlackListInsert.getRemark());
                    blackListLog.setPhotosUrl(userBlackListInsert.getPhotosUrl());
                    blackListLogs.add(blackListLog);
                }
            } else {
                throw new BaseException("System.account.notExist");
            }
            if (blackLists != null && blackLists.size() > 0) {
                userBlackListService.insertBath(blackLists);
                blackListLogService.insertBatch(blackListLogs);
            }
        } else {
            userBlackList.setUserId(user.getUserId());
            userBlackList.setAddTime(DateTimeUtil.getNowTime());

            /**查询*/
            UserBlackList userBlackListDB = userBlackListService.getByUserId(userBlackList.getUserId());

            if (userBlackListDB != null) {
                throw new BaseException("System.record.exist");
            }


            BlackListLog blackListLog = new BlackListLog();
            blackListLog.setAccountId(userBlackList.getAccountId());
            blackListLog.setUserId(userBlackList.getUserId());
            blackListLog.setUserPhone(userBlackList.getPhone());
            blackListLog.setAddAccountUserId(accountUser.getAccountUserId());
            blackListLog.setAddAccountUserPhone(accountUser.getPhone());
            blackListLog.setAddTime(userBlackList.getAddTime());
            blackListLog.setRemark(userBlackList.getRemark());
            blackListLog.setIdNO(userBlackList.getIdNO());
            blackListLog.setReason(userBlackList.getRemark());
            blackListLog.setPhotosUrl(userBlackList.getPhotosUrl());
            blackListLogs.add(blackListLog);

            userBlackListService.insert(userBlackList);
            blackListLogService.insertBatch(blackListLogs);
        }

        if (state == null) {
            state = 0;
        }
        /** 添加用户消息*/
        if (state.equals(1)) {
            List<UserBlackList> userList = new LinkedList<>();
            if (idNOSwitch.equals(0)) {
                userList.add(userBlackList);
            } else {
                userList = blackLists;
            }

            for (UserBlackList userBlackList1 : userList) {
                UserMsg userMsg = new UserMsg();
                userMsg.setMsgType(UserMsgConstant.UserMsg_PERSON);
                userMsg.setUserId(userBlackList1.getUserId());
                userMsg.setCreateTime(userBlackList1.getAddTime());
                userMsg.setMsgState(0);
                userMsg.setTitle("你被加入黑名单，限制骑行");
                userMsg.setContent("用户您好，因违反平台规定，您的账户被加入黑名单（至" + userBlackList.getExpireTime() + "），请规范用车。");
                userMsg.setRemark("运维端发送");
                userMsgService.insert(userMsg);
            }
        }

        // 添加用户操作日志
        AccountUser loginUser = LoginUserContextHolder.getLoginUser();
        userOpLogService.insertSingle(UserOpLog.builder()
                .accountId(user.getAccountId())
                .opUser(loginUser.getName())
                .opUserPhone(loginUser.getPhone())
                .targetUser(user.getName())
                .targetUserPhone(user.getPhone())
                .operation("用户账号管理")
                .opType("拉入黑名单")
                .opPlatform(OperationPlatform.MAINTAIN.code)
                .opTime(LocalDateTime.now())
                .result(true)
                .build());

        return JsonResult.succ();
    }

    /**
     * 更新
     */
    @RequestMapping("/edit")
    @OperateLog(module = ModuleEnum.USERBLACKLIST, methods = MethodEnum.USERBLACKLIST_EDIT)
    public JsonResult edit(String token, UserBlackList userBlackList) {
        /* 校验 */
        Assert.notNull(userBlackList.getUserId(), "User.userId.notNull");

        /**查询*/
        UserBlackList userBlackListDB = userBlackListService.getByUserId(userBlackList.getUserId());

        /**替换可修改字段*/
        ObjectUtil.assign(userBlackList, userBlackListDB, null);

        userBlackListService.update(userBlackListDB);

        LogUtil.info("黑名单更新：" + userBlackList.toString());

        return JsonResult.succ();
    }

    /**
     * 更新用户黑名单
     */
    @RequestMapping("/editUserBlackList")
    public Result<String> editUserBlackList(UserBlackList userBlackList,
                           @RequestParam(value = "state", required = false, defaultValue = "0") Integer state,
                           @RequestParam(value = "idNOSwitch", required = false, defaultValue = "0") Integer idNOSwitch) {
        /* 校验 */
        Assert.notNull(userBlackList.getAccountId(), "User.accountId.notNull");
        Assert.notNull(userBlackList.getUserId(), "User.userId.notNull");
        Assert.notNull(userBlackList.getExpireTime(), "User.expireTime.notNull");
        Assert.notNull(userBlackList.getRemark(), "User.remark.notNull");

        userBlackListService.update(userBlackList);

        LogUtil.info("黑名单更新：" + userBlackList.toString());

        /** 同时拉黑身份证*/
        if (idNOSwitch.equals(1)) {
            User user = userService.getByUserId(userBlackList.getUserId());
            List<User> users = userService.getAccountIdIdNO(userBlackList.getAccountId(), user.getIdNO());
            Integer accountId = userBlackList.getAccountId();
            Account account = accountService.getByAccountId(accountId);
            Account accountBrand = accountService.getByAccountId(account.getParentId());
            List<UserBlackList> blackLists = new ArrayList<>();
            List<BlackListLog> blackListLogs = new ArrayList<>();
            for (User userBlack : users) {

                UserBlackList userBlackListInsert = new UserBlackList();
                userBlackListInsert.setAccountId(accountBrand.getAccountId());
                userBlackListInsert.setUserId(userBlack.getUserId());
                userBlackListInsert.setAddTime(DateTimeUtil.getNowTime());
                userBlackListInsert.setIdNO(userBlack.getIdNO());
                userBlackListInsert.setRemark(userBlackList.getRemark());
                userBlackListInsert.setExpireTime(userBlackList.getExpireTime());
                userBlackListInsert.setPhone(userBlack.getPhone());
                blackLists.add(userBlackListInsert);

                AccountUser loginUser = LoginUserContextHolder.getLoginUser();
                BlackListLog blackListLog = new BlackListLog();
                blackListLog.setAccountId(userBlackListInsert.getAccountId());
                blackListLog.setUserId(userBlackListInsert.getUserId());
                blackListLog.setUserPhone(userBlackListInsert.getPhone());
                blackListLog.setAddAccountUserId(loginUser.getAccountUserId());
                blackListLog.setAddAccountUserPhone(loginUser.getPhone());
                blackListLog.setAddTime(userBlackListInsert.getAddTime());
                blackListLog.setRemark(userBlackListInsert.getRemark());
                blackListLog.setIdNO(userBlackListInsert.getIdNO());
                blackListLog.setReason(userBlackListInsert.getRemark());
                blackListLogs.add(blackListLog);
            }
            if (!CollectionUtils.isEmpty(blackLists)) {
                userBlackListService.insertBath(blackLists);
                blackListLogService.insertBatch(blackListLogs);
            }
        }

        /** 是否发送消息*/
        if (state.equals(1)) {
            UserMsg userMsg = new UserMsg();
            userMsg.setMsgType(UserMsgConstant.UserMsg_PERSON);
            userMsg.setUserId(userBlackList.getUserId());
            userMsg.setCreateTime(DateTimeUtil.getNowTime());
            userMsg.setMsgState(0);
            userMsg.setTitle("你被加入黑名单，限制骑行");
            userMsg.setContent("用户您好，因违反平台规定，您的账户被加入黑名单（至" + userBlackList.getExpireTime() + "），请规范用车。");
            userMsg.setRemark("运维端发送");
            userMsgService.insert(userMsg);
        }

        return Result.success();
    }

    /**
     * 删除
     */
    @RequestMapping("/del")
    @OperateLog(module = ModuleEnum.USERBLACKLIST, methods = MethodEnum.USERBLACKLIST_DEL)
    public JsonResult del(String token, Integer userId,
                          @RequestParam(value = "idNO", required = false) String idNO) {

        AccountUser accountUser = tokenService.getAccount(token);


        if (idNO != null) {
            userBlackListService.delIdNO(idNO);
        } else {
            userBlackListService.del(userId);
        }

        LogUtil.info(accountUser.getAccountUserId() + "," + accountUser.getName() + ",删除黑名单userId:" + userId + ",删除身份证号：" + idNO);
        // 插入用户操作日志
        User user = userService.getByUserId(userId);
        AccountUser loginUser = LoginUserContextHolder.getLoginUser();
        userOpLogService.insertSingle(UserOpLog.builder()
                        .accountId(user.getAccountId())
                        .opUser(loginUser.getName())
                        .opUserPhone(loginUser.getPhone())
                        .targetUser(user.getName())
                        .targetUserPhone(user.getPhone())
                        .operation("用户账号管理")
                        .opType("移除黑名单")
                        .opPlatform(OperationPlatform.MAINTAIN.code)
                        .opTime(LocalDateTime.now())
                        .result(true)
                        .build()
                );
        return JsonResult.succ();
    }

    /**
     * 根据平台账号id查询
     */
    @RequestMapping("/getByAccountId")
    public JsonResult getByAccountId(String token, Integer accountId) {
        Assert.notNull(accountId, "AccountUser.agentId.notNull");

        /**查询品牌id*/
        Account account = accountService.getByAccountId(accountId);
        if (account == null) {
            throw new BaseException("System.account.notExist");
        }

        Account accountAgent = accountService.getByAccountId(account.getParentId());
        if (accountAgent == null) {
            throw new BaseException("System.account.notExist");
        }

        List<UserBlackList> userBlackList = userBlackListService.getByAccountId(accountAgent.getParentId());

        return JsonResult.succ(userBlackList);
    }

    /**
     * 根据平台账号id分页查询
     */
    @RequestMapping("/getByAccountIdPaging")
    public JsonResult getByAccountIdPaging(String token, Integer accountId, Integer rowCount, Integer pageNO) {
        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        /**查询品牌id*/
        Account account = accountService.getByAccountId(accountId);
        if (account == null) {
            throw new BaseException("System.account.notExist");
        }

        Account accountAgent = accountService.getByAccountId(account.getParentId());
        if (accountAgent == null) {
            throw new BaseException("System.account.notExist");
        }

        if (rowCount == null) {
            rowCount = 10;
        }

        if (pageNO == null) {
            pageNO = 1;
        }

        Integer accountIdPaingCount = userBlackListService.getByAccountIdCount(accountAgent.getParentId());

        List<UserBlackList> userBlackList = new ArrayList<>();
        if (accountIdPaingCount > 0) {
            userBlackList = userBlackListService.getByAccountIdPaing(accountAgent.getParentId(), pageNO, rowCount);
        }

        return JsonResult.succ(accountIdPaingCount, userBlackList);

    }

    /**
     * 根据手机号搜索
     */
    @RequestMapping("/getByPhone")
    public JsonResult getByPhone(String token, Integer accountId, String phone,
                                 @RequestParam(value = "idNO", required = false) String idNO) {
        Assert.notNull(accountId, "AccountUser.agentId.notNull");

        /**查询品牌id*/
        Integer account = accountService.getByAccount(accountId);
        if (account == null) {
            throw new BaseException("System.account.notExist");
        }

        List<UserBlackList> userBlackLists = new LinkedList<>();

        if (phone != null) {
            /**查询用户id*/
            User user = userService.getByPhone(account, phone);
            if (user == null) {
                throw new BaseException("System.account.notExist");
            }

            /**查询*/
            UserBlackList userBlackListDB = userBlackListService.getByUserId(user.getUserId());
            if (userBlackListDB != null) {
                userBlackLists.add(userBlackListDB);
            }
        } else if (idNO != null) {
            /**查询*/
            userBlackLists = userBlackListService.getByIdNO(account, idNO);
        } else {
            throw new BaseException("Machine.control.paramName.notNull");
        }

        return JsonResult.succ(userBlackLists);
    }

    /**
     * 预拉黑功能
     *
     * @param token
     * @param phones
     * @param expireTime
     * @return
     */
    @RequestMapping("/addBatchWithNotExist")
    public JsonResult addBatchWithNotExist(String token, String phones, String expireTime) {
        AccountUser accountUser = tokenService.getAccount(token);
        userBlackListService.setUserBlackListByPhoneBatch(accountUser.getAccountId(), phones, expireTime,null);
        return JsonResult.succ();
    }
}